package com.hcc.gateway.common.utils;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.hcc.gateway.common.domain.RespBody;
import com.hcc.gateway.domain.enums.ContentTypeEnum;
import com.hcc.gateway.domain.enums.HttpMethodEnum;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * HttpClientUtils
 *
 * @author shengjun.hu
 * @date 2022/1/20
 */
public class HttpClientUtils {

    private HttpClientUtils() {}

    public static String get(String url) {
        return get(url, null);
    }

    public static String get(String url, Map<String, Object> queryMap) {
        return null;
    }

    public static String post(String url, String json) {
        return null;
    }

    public static String post(String url, Map<String, Object> paramMap) {
        return null;
    }

    @SuppressWarnings("unchecked")
    public static RespBody method(String url, String method, Map<String, String> headers, String contentType, Object paramObj) {
        OkHttpClient okHttpClient = new OkHttpClient();

        Request.Builder builder = new Request.Builder();
        RequestBody requestBody = null;
        if (HttpMethodEnum.POST.name().equals(method) || HttpMethodEnum.PUT.name().equals(method)) {
            if (ContentTypeEnum.FORM_URLENCODED.getCode().equals(contentType)) {
                FormBody.Builder formBuilder = new FormBody.Builder();
                Map<String, Object> paramMap = (Map<String, Object>) paramObj;
                paramMap.forEach((k, v) -> {
                    if (v == null) {
                        return;
                    }
                    if (Collection.class.isAssignableFrom(v.getClass())) {
                        Collection<Object> coll = (Collection<Object>) v;
                        for (Object o : coll) {
                            if (o == null) {
                                continue;
                            }
                            formBuilder.add(k, o.toString());
                        }
                    } else {
                        formBuilder.add(k, v.toString());
                    }
                });
                requestBody = formBuilder.build();
            } else if (ContentTypeEnum.JSON.getCode().equals(contentType)
                    || ContentTypeEnum.TEXT_PLAIN.getCode().equals(contentType)
                    || ContentTypeEnum.TEXT_XML.getCode().equals(contentType)
                    || ContentTypeEnum.TEXT_HTML.getCode().equals(contentType)) {
                if (paramObj == null || paramObj instanceof String) {
                    requestBody = RequestBody.create(MediaType.parse(contentType), paramObj == null ? "" : paramObj.toString());
                } else if (ContentTypeEnum.JSON.getCode().equals(contentType) && paramObj instanceof Map) {
                    requestBody = RequestBody.create(MediaType.parse(contentType), JsonUtils.writeValueAsString(paramObj));
                } else {
                    throw new IllegalArgumentException("非法的参数！");
                }
            }
        }

        builder.url(url).method(method, requestBody);
        if (MapUtil.isNotEmpty(headers)) {
            headers.forEach(builder::addHeader);
        }

        Call call = okHttpClient.newCall(builder.build());
        try (Response response = call.execute()) {
            RespBody respBody = new RespBody();
            respBody.setCode(response.code());
            respBody.setMessage(response.message());
            if (response.isSuccessful()) {
                Map<String, List<String>> respHeaders = new HashMap<>();
                for (String name : response.headers().names()) {
                    respHeaders.put(name, response.headers().values(name));
                }
                respBody.setHeaders(respHeaders);
                ResponseBody body = response.body();
                if (body != null) {
                    if (body.contentType() != null) {
                        respBody.setContentType(body.contentType().toString());
                    }
                    if (StrUtil.isEmpty(respBody.getContentType())) {
                        respBody.setBytes(body.bytes());
                    } else {
                        if (respBody.getContentType().contains(ContentTypeEnum.JSON.getCode())
                                || respBody.getContentType().contains(ContentTypeEnum.XML.getCode())
                                || respBody.getContentType().contains(ContentTypeEnum.TEXT_PLAIN.getCode())
                                || respBody.getContentType().contains(ContentTypeEnum.TEXT_XML.getCode())
                                || respBody.getContentType().contains(ContentTypeEnum.TEXT_HTML.getCode())) {
                            respBody.setStringBody(body.string());
                        } else {
                            respBody.setBytes(body.bytes());
                        }
                    }
                }
            }
            return respBody;
        } catch (Exception e) {
            throw new RuntimeException(String.format("请求地址：[%s]失败！", url), e);
        }
    }

    public static RespBody method(String url, String method, String contentType, Object paramObj) {
        return method(url, method, null, contentType, paramObj);
    }

}
